/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.mzk.oai.repositoryManager.collections;

import cz.mzk.oai.repositoryManager.AbstractEntityManager;
import cz.mzk.oai.repositoryManager.EntityNotFoundException;
import cz.mzk.oai.repositoryManager.EntityPresentException;
import cz.mzk.oai.repositoryManager.IncorrectEntityException;
import cz.mzk.oai.repositoryManager.NotEmptyException;
import cz.mzk.oai.repositoryManager.items.ItemEntity;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.NoResultException;
import javax.persistence.Query;

/**
 *
 * @author Martin Rehanek (rehan@mzk.cz)
 */
public class CollectionManagerImpl extends AbstractEntityManager implements CollectionManager {

    private static final String QUERY_FIND_BY_NAME = "SELECT c FROM " + CollectionEntity.class.getSimpleName() + " c WHERE c.name = :name";

    public CollectionEntity findCollection(String name) throws EntityNotFoundException {
        checkParameters(name);
        String queryStr = QUERY_FIND_BY_NAME;
        Query query = getEntityManager().createQuery(queryStr);
        query.setParameter("name", name);
        try {
            CollectionEntity result = (CollectionEntity) query.getSingleResult();
            return result;
        } catch (NoResultException ex) {
            throw new EntityNotFoundException(CollectionEntity.class.getCanonicalName(), "name: '" + name + "'");
        }
    }

    private boolean collectionExists(String name) {
        Query query = getEntityManager().createQuery(QUERY_FIND_BY_NAME);
        query.setParameter("name", name);
        return !super.isEmpty(query);
    }

    public CollectionEntity createCollection(String name) throws EntityPresentException {
        checkParameters(name);
        if (collectionExists(name)) {
            throw new EntityPresentException(getEntityClassName(), "name: '" + name + "'");
        }
        CollectionEntity collection = new CollectionEntity();
        collection.setName(name);
//        Set<ItemEntity> items = new HashSet<ItemEntity>();
//        collection.setItems(items);
        getEntityManager().getTransaction().begin();
        getEntityManager().persist(collection);
        getEntityManager().getTransaction().commit();

        return collection;
    }

    public void checkParameters(String name) {
        if (name == null) {
            throw new NullPointerException("name");
        }
    }

    public void removeCollection(CollectionEntity collection) throws NotEmptyException, IncorrectEntityException {
        if (!isManagedEntity(collection)) {
            throw new IncorrectEntityException(getEntityClassName(), getEntityIdString(collection));
        }
        if (collection.getItems() == null) {
            throw new IncorrectEntityException(getEntityClassName(), getEntityIdString(collection));
        }
        if (!collection.getItems().isEmpty()) {
            throw new NotEmptyException(getEntityClassName(), getEntityIdString(collection));
        }

        getEntityManager().getTransaction().begin();
        try {
            getEntityManager().remove(collection);
        } catch (IllegalArgumentException e) {
            throw new IncorrectEntityException(getEntityClassName(), getEntityIdString(collection));
        } finally {
            getEntityManager().getTransaction().commit();
        }
    }

    protected String getEntityClassName() {
        return CollectionEntity.class.getCanonicalName();
    }

    @Override
    protected String getEntityIdString(Object entity) {
        if (!(entity instanceof CollectionEntity)) {
            throw new IllegalArgumentException("not instance of " + CollectionEntity.class.getCanonicalName());
        }
        CollectionEntity collection = (CollectionEntity) entity;
        StringBuilder result = new StringBuilder();
        result.append("id:").append(collection.getId());
        result.append(", name:").append(collection.getName());
        return result.toString();
    }
}
